www.gusucode.com > VC++ 界面很酷的一款多媒体播放器 > VC++ 界面很酷的一款多媒体播放器/gusucode/xMedia代码注释中/player.cpp

    //Download by http://www.NewXing.com
/****************************************
*	File:			player.cpp			*
*	Last modified:	2004.3.24			*
*	Author:			Yuanyi-Zhang		*
*	Version:		0.0.1.0				*
*	CopyLeft 2004   xMedia team			*
****************************************/
/****************************************************************
*																*
* This file may be distributed and/or modified under the terms	*
* of the GNU General Public License version 2 as published by	*
* the Free Software Foundation and appearing in the file		*
* LICENSE.GPL included in the packaging of this file.			*
*																*
****************************************************************/

#pragma warning(disable:4786)

#include <tchar.h>

#include "player.h"
#include "messagedef.h"

Player::Player()
{
	m_pGraph = NULL;
	m_pMediaControl = NULL;
	m_pEvent = NULL;
	m_pVidWin = NULL;
	m_pSeeking = NULL;
	m_PlayState = Uninited;
	m_AudioOnly = true;
	m_fnameBuf = _T("");
	m_pBA = NULL;
	m_pBV = NULL;
}
/////////////////////////////////
//初始化DirectShow设备
bool Player::initDevice()
{
	CoCreateInstance( CLSID_FilterGraph, NULL, CLSCTX_INPROC,
                     IID_IGraphBuilder, (void **)&m_pGraph);

	if( m_pGraph == NULL )
	{
		m_ErrorString = _T("创建DirectShow组件失败");
		return false;
	}

    m_pGraph->QueryInterface(IID_IVideoWindow, (void **)&m_pVidWin);
    m_pGraph->QueryInterface( IID_IMediaEventEx, (void **)&m_pEvent);
    m_pGraph->QueryInterface(IID_IMediaControl, (void **)&m_pMediaControl);
	m_pGraph->QueryInterface( IID_IMediaSeeking, (void**)&m_pSeeking );
	m_pGraph->QueryInterface( IID_IBasicVideo, (void**)&m_pBV );
	m_pGraph->QueryInterface( IID_IBasicAudio, (void**)&m_pBA );

	if( m_pSeeking == NULL || m_pMediaControl == NULL
		|| m_pEvent == NULL || m_pBA == NULL )
	{
		m_ErrorString = _T("创建DirectShow组件失败");
		return false;
	}

	m_PlayState = Inited;

	return true;
}
///////////////////////////////
//打开指定文件
bool Player::Open( string filePath )
{
	if( m_fnameBuf.compare( filePath ) == 0 && 
		m_PlayState != Uninited )
	{
		return true;
	}

	if( m_PlayState != Uninited )
	{
		Close();
	}

	m_fnameBuf = filePath;

	if( !initDevice() )
	{
		return false;
	}

	if( ! m_pGraph || ! m_pMediaControl )
	{
		m_ErrorString = _T("DirectDraw未被正确初始化");
		return false;
	}

	HRESULT hres;
	unsigned short wcFileName[MAX_PATH];

	MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,
					filePath.c_str(),
					filePath.size()+1,
					wcFileName,MAX_PATH);

	hres = m_pGraph->RenderFile( wcFileName, NULL );
	
	if( !checkRes( hres ) )
	{
		return false;
	}

	long  videoWidth;

	if( !m_pBV )
	{
		m_AudioOnly = true;
	}
	else
	{
		hres = m_pBV->get_VideoWidth( &videoWidth );
		if( checkRes( hres ) )
		{
			m_AudioOnly = false;
		}
		else
		{
			m_AudioOnly = true;
		}
	}

	if( !m_AudioOnly )
	{
		ShowWindow( m_hWndVideo, SW_SHOW );

		hres = m_pVidWin->put_Owner((OAHWND)m_hWndVideo);

		if( !checkRes( hres ) )
		{
			return false;
		}
    
		hres = m_pVidWin->put_WindowStyle( WS_CHILD | WS_CLIPSIBLINGS);
			
		if( !checkRes( hres ) )
		{
			return false;
		}
		
		m_pVidWin->put_Left( m_VideoWndRect.left );
		m_pVidWin->put_Top( m_VideoWndRect.top );
		m_pVidWin->put_Width( m_VideoWndRect.right - m_VideoWndRect.left );
		m_pVidWin->put_Height( m_VideoWndRect.bottom - m_VideoWndRect.top );
	}

	return true;
}
///////////////////////////////
//关闭DirectShow设备
void Player::Close()
{
	if( m_pMediaControl )
	{
		m_pMediaControl->Stop();
	}

	m_PlayState = Uninited;
	m_AudioOnly = true;
	m_FullScreen = false;

	ShowWindow( m_hWndVideo, SW_HIDE );

	ReleaseResource();
}
///////////////////////////////
//释放资源
void Player::ReleaseResource()
{
	//清除DirectShow组件
	if( m_pVidWin )
	{
		m_pVidWin->put_Visible( OAFALSE );
		m_pVidWin->put_Owner( NULL );
		m_pVidWin = NULL;
	}

	if( m_pEvent )
	{
		m_pEvent->SetNotifyWindow( NULL, 0, 0 );
		m_pEvent->Release();
		m_pEvent = NULL;
	}

	if( m_pMediaControl )
	{
		m_pMediaControl->Stop();
		m_pMediaControl->Release();
		m_pMediaControl = NULL;
	}

	if( m_pBV )
	{
		m_pBV->Release();
		m_pBV = NULL;
	}

	if( m_pBA )
	{
		m_pBA->Release();
		m_pBA = NULL;
	}

	if( m_pGraph )
	{
		m_pGraph->Release();
		m_pGraph = NULL;
	}
}

////////////////////////////////////
//播放文件
bool Player::Play( string filePath )
{
	if( !Open( filePath ) )
	{
		return false;
	}

	if( m_PlayState == Running )
	{
		return true;
	}

	HRESULT hres = m_pMediaControl->Run();
	
	m_PlayState = Running;

	return checkRes( hres );
}
///////////////////////////////
//停止播放
bool Player::Stop()
{
	if( m_PlayState != Running &&
		m_PlayState != Paused )
	{
		return true;
	}

	HRESULT hres = m_pMediaControl->Stop();
	
	LONGLONG pos = 0;

	m_pSeeking->SetPositions(&pos, AM_SEEKING_AbsolutePositioning ,
            NULL, AM_SEEKING_NoPositioning);

	m_pMediaControl->Pause();

	m_PlayState = Stopped;

	return true;
}
///////////////////////////////
//暂停播放
bool Player::Pause()
{
	if( m_PlayState != Running )
	{
		return false;
	}

	HRESULT hres = m_pMediaControl->Pause();

	m_PlayState = Paused;

	return checkRes( hres );
}
///////////////////////////////
//检查返回值是否有效
bool Player::checkRes( HRESULT hres )
{
	switch( hres )
	{
	case E_FAIL:
		m_ErrorString = _T("播放失败,可能是由于设备未被初始化");
		return false;
	case E_INVALIDARG:
		m_ErrorString = _T("播放失败,错误的参数");
		return false;
	case E_NOTIMPL:
		m_ErrorString = _T("播放失败,接口不支持此方法");
		return false;
	case E_OUTOFMEMORY:
		m_ErrorString = _T("播放失败,没有足够的缓冲区用于播放此文件");
		return false;
	case E_POINTER:
		m_ErrorString = _T("播放失败,参数含有空指针");
		return false;
	case E_UNEXPECTED:
		m_ErrorString = _T("播放失败,不可预测的错误");
		return false;
	case S_FALSE:
	case S_OK:
		return true;
	}
	return false;
}
/////////////////////////////
//定位播放进度
bool Player::seeking( int prog )
{
	if( m_PlayState == Uninited )
	{
		m_ErrorString = _T("组件未被初始化");
		return false;
	}

	LONGLONG playTime,length;

	m_pSeeking->GetDuration( &length );
	playTime = (length * prog) / 100;
	m_pSeeking->SetPositions( &playTime, AM_SEEKING_AbsolutePositioning, NULL, AM_SEEKING_NoPositioning );

	return true;
}
/////////////////////////////
//获取播放Bps,未实现
long Player::getBPS()
{
	if( m_PlayState != Uninited )
	{
		return 192;
	}
	return 0;
}
/////////////////////////////
//获取播放曲目长度
long Player::getLength()
{
	LONGLONG length;

	if( m_pSeeking )
	{
		m_pSeeking->GetDuration( &length );
		return length/10000000;
	}
	return 0;
}
/////////////////////////////
//获取播放进度
int Player::getPlayProg()
{
	if( m_PlayState == Uninited )
	{
		return 0;
	}

	LONGLONG playTime,length;

	m_pSeeking->GetPositions( &playTime, &length );
	m_pSeeking->GetDuration( &length );

	if( playTime == length )
	{
		Close();
		PostThreadMessage( GetCurrentThreadId(), MC_PLAYNEXT, 0, 0 );
		return 0;
	}

	return (int)((playTime*100)/length);
}